home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / macos / uae069b2.src.cpt.hqx / UAE069ß2.SRC.CPT / uae069fl2.src / zfile.c < prev    next >
C/C++ Source or Header  |  1997-03-09  |  4KB  |  227 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * routines to handle compressed file automatically
  5.   *
  6.   * (c) 1996 Samuel Devulder, Tim Gunn
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "zfile.h"
  15.  
  16. #ifdef USE_ZFILE
  17.  
  18. #ifdef AMIGA
  19. extern char *amiga_dev_path;   /* dev: */
  20. extern char *ixemul_dev_path;  /* /dev/ */
  21. extern int readdevice(const char *, char *);
  22. #endif
  23.  
  24. static struct zfile
  25. {
  26.   struct zfile *next;
  27.   FILE *f;
  28.   char name[L_tmpnam];
  29. } *zlist;
  30.  
  31. /*
  32.  * called on exit()
  33.  */
  34. void zfile_exit(void)
  35. {
  36.   struct zfile *l;
  37.  
  38.   while((l = zlist))
  39.     {
  40.       zlist = l->next;
  41.       fclose(l->f);
  42.       free(l);
  43.     }
  44. }
  45.  
  46. /*
  47.  * fclose() but for a compressed file
  48.  */
  49. int zfile_close(FILE *f)
  50. {
  51.   struct zfile *pl = NULL,
  52.                *l  = zlist;
  53.   int ret;
  54.  
  55.   while(l && l->f!=f) {pl = l;l=l->next;}
  56.   if(!l) return fclose(f);
  57.   ret = fclose(l->f);
  58.  
  59.   if(!pl) zlist = l->next;
  60.   else pl->next = l->next;
  61.   free(l);
  62.  
  63.   return ret;
  64. }
  65.  
  66. /*
  67.  * gzip decompression
  68.  */
  69. static int gunzip(const char *src, const char *dst)
  70. {
  71.   char cmd[1024];
  72.   if(!dst) return 1;
  73.   sprintf(cmd,"gzip -d -c %s >%s",src,dst);
  74.   return !system(cmd);
  75. }
  76.  
  77. /*
  78.  * lha decompression
  79.  */
  80. static int lha(const char *src, const char *dst)
  81. {
  82.   char cmd[1024];
  83.   if(!dst) return 1;
  84. #if defined(AMIGA)
  85.   sprintf(cmd,"lha -q -N p %s >%s",src,dst);
  86. #else
  87.   sprintf(cmd,"lha pq %s >%s",src,dst);
  88. #endif
  89.   return !system(cmd);
  90. }
  91.  
  92. /*
  93.  * (pk)unzip decompression
  94.  */
  95. static int unzip(const char *src, const char *dst)
  96. {
  97.   char cmd[1024];
  98.   if(!dst) return 1;
  99. #if defined(AMIGA)
  100.   sprintf(cmd,"unzip -p %s '*.adf' >%s",src,dst);
  101.   return !system(cmd);
  102. #else
  103.   return gunzip(src,dst); /* I don't know for unix */
  104. #endif
  105. }
  106.  
  107. /*
  108.  * decompresses the file (or check if dest is null)
  109.  */
  110. static int uncompress(const char *name, char *dest)
  111. {
  112.     char *ext = strrchr(name, '.');
  113.     char nam[1024];
  114.  
  115.     if (ext != NULL && access(name,0) >= 0) {
  116.     ext++;
  117.     if(!strcasecmp(ext,"z")  ||
  118.        !strcasecmp(ext,"gz") ||
  119.        !strcasecmp(ext,"adz") ||
  120.        !strcasecmp(ext,"roz") ||
  121.        0) return gunzip(name,dest);
  122. #ifndef __DOS__
  123.     if(!strcasecmp(ext,"lha") ||
  124.        !strcasecmp(ext,"lzh") ||
  125.        0) return lha(name,dest);
  126.     if(!strcasecmp(ext,"zip") ||
  127.        0) return unzip(name,dest);
  128. #endif
  129.     }
  130.  
  131.     if(access(strcat(strcpy(nam,name),".z"),0)>=0  ||
  132.        access(strcat(strcpy(nam,name),".Z"),0)>=0  ||
  133.        access(strcat(strcpy(nam,name),".gz"),0)>=0 ||
  134.        access(strcat(strcpy(nam,name),".GZ"),0)>=0 ||
  135.        access(strcat(strcpy(nam,name),".adz"),0)>=0 ||
  136.        access(strcat(strcpy(nam,name),".roz"),0)>=0 ||
  137.        0) return gunzip(nam,dest);
  138.  
  139. #ifndef __DOS__
  140.     if(access(strcat(strcpy(nam,name),".lha"),0)>=0 ||
  141.        access(strcat(strcpy(nam,name),".LHA"),0)>=0 ||
  142.        access(strcat(strcpy(nam,name),".lzh"),0)>=0 ||
  143.        access(strcat(strcpy(nam,name),".LZH"),0)>=0 ||
  144.        0) return lha(nam,dest);
  145.  
  146.     if(access(strcat(strcpy(nam,name),".zip"),0)>=0 ||
  147.        access(strcat(strcpy(nam,name),".ZIP"),0)>=0 ||
  148.        0) return unzip(nam,dest);
  149. #endif
  150.  
  151. #if defined(AMIGA)
  152.     if(!strnicmp(nam,ixemul_dev_path,strlen(ixemul_dev_path)))
  153.     return readdevice(name+strlen(ixemul_dev_path),dest);
  154.     if(!strnicmp(nam,amiga_dev_path,strlen(amiga_dev_path)))
  155.     return readdevice(name+strlen(amiga_dev_path),dest);
  156. #endif
  157.  
  158.     return 0;
  159. }
  160.  
  161. /*
  162.  * fopen() for a compressed file
  163.  */
  164. FILE *zfile_open(const char *name, const char *mode)
  165. {
  166.     struct zfile *l;
  167.     int fd = 0;
  168.     
  169.     if(! uncompress (name,NULL))
  170.     return fopen (name, mode);
  171.     
  172.     l = malloc (sizeof *l);
  173.     if (!l)
  174.     return NULL;
  175.  
  176.     tmpnam(l->name);
  177. #if !defined(AMIGA)
  178.     /* On the amiga this would make ixemul loose the break handler */
  179.     fd = creat(l->name, 0666);
  180.     if (fd < 0)
  181.     return NULL;
  182. #endif
  183.     
  184.     if(!uncompress(name,l->name)) 
  185.     {
  186.     free(l); close (fd); unlink(l->name); return NULL; 
  187.     }
  188.  
  189.     l->f = uae_fopen_del (l->name,mode);
  190.  
  191. #if !defined(AMIGA)
  192.     close (fd);
  193. #endif
  194.     
  195.     if (l->f == NULL) {
  196.     free(l);
  197.     return NULL;
  198.     }
  199.  
  200.     l->next = zlist;
  201.     zlist   = l;
  202.  
  203.     return l->f;
  204. }
  205.  
  206. #else
  207.  
  208. /*
  209.  * Stubs for machines that this doesn't work on.
  210.  */
  211.  
  212. void zfile_exit(void)
  213. {
  214. }
  215.  
  216. int zfile_close(FILE *f)
  217. {
  218.     return fclose(f);
  219. }
  220.  
  221. FILE *zfile_open(const char *name, const char *mode)
  222. {
  223.     return fopen(name, mode);
  224. }
  225.  
  226. #endif
  227.